<?php
//
//	file: download.php
//	author: ptirhiik
//	begin: 10/12/2003
//	version: 1.6.2 - 22/01/2008
//	license: http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
//

define('IN_PHPBB', true);

$phpbb_root_path = './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
$requester = 'download';
include($phpbb_root_path . 'common.' . $phpEx);

define('DL_TEXT_SIZE', 2048); // limit text size for desc file
$dirname = $phpbb_root_path . (empty($config->data['download_path']) ? 'download/' : $config->data['download_path']);
$root_name = $dirname;

//
// Start session management
//
$userdata = session_pagestart($user_ip, PAGE_INDEX);
$user->set($requester, array('download'));
//
// End session management
//

if ( empty($images['Zip_file']) )
{
	$images['Zip_file'] = 'images/zip.gif';
}
if ( empty($images['Zip_mini']) )
{
	$images['Zip_mini'] = 'images/zip_mini.gif';
}

define('ITEM', 0);
define('CAT', 1);
define('NODE', 2);

class file_tree
{
	var $requester;
	var $data;
	var $catalog;
	var $last_id;
	var $default_type;

	function file_tree($requester, $dirname, $collapse=true)
	{
		$this->requester = $requester;
		$this->default_type = $collapse ? NODE : CAT;
		$this->data = array(0 => array('path' => $dirname, 'type' => $this->default_type, 'time' => 0));
		$this->catalog = array();
		$this->last_id = 0;
	}

	function read()
	{
		$this->read_catalog();
		$this->read_node(0);
		$this->rebuild_catalog();
	}

	function read_catalog()
	{
		$name = $this->data[0]['path'] . '/catalog' . strrchr(__FILE__, '.');
		$this->catalog = array($this->data[0]['path'] => 0);
		if ( ($filename = phpbb_realpath($name)) && file_exists($filename) )
		{
			include($name);
		}
		$this->last_id = 0;
		if ( count($this->catalog) > 1 )
		{
			$tkeys = array_flip($this->catalog);
			krsort($tkeys);
			$this->last_id = key($tkeys);
			unset($tkeys);
		}
	}

	function rebuild_catalog()
	{
		$this->catalog = array();
		foreach ( $this->data as $id => $data )
		{
			$this->catalog[ $data['path'] . (isset($data['file']) ? $data['file'] : '') ] = $id;
		}
	}

	function send_catalog()
	{
		$text = '<?php
// download catalog: ' . gmdate('d/m/Y - H:i:s') . ' GMT
if ( !defined(\'IN_PHPBB\') )
{
	die(\'Hack attempt!\');
}

$this->catalog = array(';
		foreach ( $this->catalog as $file => $id )
		{
			$text .= '
	\'' . str_replace('\'', '\\\'', $file) . '\' => ' . intval($id) . ',';
		}
		$text .= '
);

?>';
		$filename = 'catalog' . strrchr(__FILE__, '.');
		header('Content-Type: text/x-delimtext; name="' . $filename . '"');
		header('Content-disposition: attachment; filename=' . $filename);
		echo $text;
	}

	function get_id($fullpath)
	{
		if ( isset($this->catalog[$fullpath]) )
		{
			return $this->catalog[$fullpath];
		}
		else
		{
			$this->last_id++;
			return $this->last_id;
		}
	}

	function read_node($parent)
	{
		$dscs = array();
		$dirs = array();
		$zips = array();
		$parent_path = empty($parent) ? $this->data[$parent]['path'] : $this->data[$parent]['path'] . $this->data[$parent]['file'] . '/';
		$handle = @opendir($parent_path);
		while ( $filename = readdir($handle) )
		{
			if ( !in_array($filename, array('.', '..')) )
			{
				if ( @is_dir($parent_path . $filename) )
				{
					if ( preg_match('/[^-]*-.*$/', $filename) )
					{
						$object = preg_replace('/[^-]*-(.*)$/', '$1', $filename);
						$dirs[$object] = array('file' => $filename);
					}
				}
				else if ( preg_match('/[^-]*-.*\.zip$/', $filename) )
				{
					$object = preg_replace('/[^-]*-(.*)\.zip$/', '$1', $filename);
					$zips[$object] = array('file' => $filename, 'time' => filemtime($parent_path . $filename));
				}
				else if ( preg_match('/^dsc-.*\.txt$/', $filename) )
				{
					$object = preg_replace('/^dsc-(.*)\.txt$/', '$1', $filename);
					$dscs[$object] = array('file' => $filename);
				}
			}
		}
		@closedir($handle);

		// get zips
		if ( !empty($zips) )
		{
			ksort($zips);
			foreach ( $zips as $object => $data )
			{
				if ( isset($dscs[$object]) )
				{
					$id = $this->get_id($parent_path . $data['file']);
					$this->data[$id] = array('object' => $object, 'file' => $data['file'], 'desc' => $dscs[$object]['file'], 'path' => $parent_path, 'type' => ITEM, 'parent' => $parent, 'time' => $data['time']);
					if ( !isset($this->data[$parent]['subs']) )
					{
						$this->data[$parent]['subs'] = array();
					}
					$this->data[$parent]['subs'][] = $id;
				}
			}
		}

		// get nodes
		if ( !empty($dirs) )
		{
			ksort($dirs);
			foreach ( $dirs as $object => $data )
			{
				if ( !isset($zips[$object]) )
				{
					$id = $this->get_id($parent_path . $data['file']);
					$this->data[$id] = array('object' => $object, 'file' => $data['file'], 'desc' => $dscs[$object]['file'], 'path' => $parent_path, 'type' => $this->default_type, 'parent' => $parent, 'time' => 0);
					$this->read_node($id);
					$this->data[$parent]['type'] = NODE;
					if ( !isset($this->data[$parent]['subs']) )
					{
						$this->data[$parent]['subs'] = array();
					}
					$this->data[$parent]['subs'][] = $id;
				}
			}
		}

		// get last update
		if ( $parent == 0 )
		{
			$count_data = count($this->data);
			for ( $i = $count_data-1; $i > 0; $i-- )
			{
				$this->data[ $this->data[$i]['parent'] ]['time'] = max($this->data[ $this->data[$i]['parent'] ]['time'], $this->data[$i]['time']);
			}
		}
	}

	function display($from=0, $with_lower=true)
	{
		global $template, $config, $user;

		if ( !isset($this->data[$from]) )
		{
			$from = 0;
		}
		$count_subs = count($this->data[$from]['subs']);
		$color = false;
		for ( $i = 0; $i < $count_subs; $i++ )
		{
			// send the catalog line
			if ( !$i && !$from && ($user->data['user_level'] == ADMIN) )
			{
				// prepare tpl data
				$type = ITEM;
				$template->assign_block_vars('row', array(
					'NAME' => $template->lang('Catalog'),
					'DESC' => $template->lang('Catalog_explain'),
					'TIME' => '',
					'I_FOLDER' => $template->img('Zip_file'),
					'L_FOLDER' => 'catalog' . strrchr(__FILE__, '.'),
					'U_NAME' => $config->url($this->requester, array('pack' => -1), true),
				));
				$color = !$color;
				$template->set_switch('row.light', $color);
				$template->set_switch('row.file');
				$template->set_switch('row.file.light', $color);
			}

			// go with the tree
			$sub = $this->data[$from]['subs'][$i];

			// read desc file
			$text = '';
			if ( !empty($this->data[$sub]['desc']) )
			{
				$handle = @fopen($this->data[$sub]['path'] . $this->data[$sub]['desc'], 'r');
				$text = @fread($handle, DL_TEXT_SIZE);
				@fclose($handle);
			}

			// get title and text
			$title = str_replace('_', ' ', $this->data[$sub]['object']);
			$text = str_replace(array("\t", "\n"), array('&nbsp;&nbsp;', '<br />'), htmlspecialchars($text));
			$first_linefeed = strpos($text, '<br />');
			if ( $first_linefeed )
			{
				$t_title = trim(substr($text, 0, $first_linefeed));
				if ( !empty($t_title) )
				{
					$title = $t_title;
					$text = substr($text, $first_linefeed + strlen('<br />'));
				}
			}

			// prepare tpl data
			$type = $this->data[$sub]['type'];
			if ( ($type == CAT) && !$with_lower )
			{
				$type = NODE;
			}
			$template->assign_block_vars('row', array(
				'NAME' => $title,
				'DESC' => $text,
				'TIME' => empty($this->data[$sub]['time']) ? '' : $user->date($this->data[$sub]['time']),
				'I_FOLDER' => ($type == ITEM) ? $user->img('Zip_file') : $user->img('forum'),
				'L_FOLDER' => ($type == ITEM) ? 'mod-' . $this->data[$sub]['object'] . '.zip' : ( ($type == CAT) ? _clean_html($text) : str_replace('_', ' ', $this->data[$sub]['object'])),
				'U_NAME' => ($type == ITEM) ? $this->data[$sub]['path'] . $this->data[$sub]['file'] : $config->url($this->requester, array('pack' => $sub), true),
			));
			$color = !$color;
			$template->set_switch('row.light', $color);
			if ( $type == NODE )
			{
				$template->set_switch('row.forum');
				$template->set_switch('row.forum.light', $color);
			}
			if ( $type == CAT )
			{
				$template->set_switch('row.cat');
				$color = false;
				$this->display($sub, false);
			}
			if ( $type == ITEM )
			{
				$template->set_switch('row.file');
				$template->set_switch('row.file.light', $color);
			}
		}
	}

	function navigation($from)
	{
		if ( !isset($this->data[$from]) )
		{
			$from = 0;
		}

		$stack = array();
		while ( !empty($from) )
		{
			if ( !isset($this->data[$from]) )
			{
				$from = 0;
			}
			else
			{
				$stack[] = $from;
				$from = intval($this->data[$from]['parent']);
			}
		}

		// reverse read (LIFO) and display
		$navigation = new navigation();
		$navigation->add('Index', '', INDEX, '', 'Zip_mini');
		$navigation->add('Pack_downloads', '', $this->requester, '');
		$count_stack = count($stack);
		for ( $i = $count_stack-1; $i >= 0; $i-- )
		{
			$navigation->add(trim(str_replace('_', ' ', $this->data[ $stack[$i] ]['object'])), '', $this->requester, array('pack' => $stack[$i]), '');
		}
		$navigation->display('nav', false);
	}
}

//
// process
//
$pack_id = _read('pack', TYPE_INT);
if ( ($user->data['user_level'] == ADMIN) && ($pack_id == -1) )
{
	$file_tree = new file_tree($requester, $root_name);
	$file_tree->read();
	$file_tree->send_catalog();
	unset($file_tree);
	exit;
}

// system
$template->assign_vars(array(
	'L_TITLE' => $user->lang('Pack_downloads'),
	'I_FILETYPE' => $user->img('Zip_file'),
	'L_FILENAME' => $user->lang('Filename'),
	'L_DATE' => $user->lang('Last_updated'),
	'S_ACTION' => $config->url($requester),
));
_hide_set();

$page_title = $user->lang('Pack_downloads');
$navigation = new navigation();
$navigation->add('Pack_downloads', '', $requester, '', 'Zip_mini');

$file_tree = new file_tree($requester, $root_name);
$file_tree->read();
$pack_id = isset($file_tree->data[$pack_id]) ? $pack_id : 0;
$file_tree->display($pack_id);

$file_tree->navigation($pack_id);

// send to browser
include ($config->url('includes/page_header'));
$template->set_filenames(array('body' => 'download_body.tpl'));
$template->pparse('body');
include($config->url('includes/page_tail'));

?>